<?php
require_once __DIR__ . '/vendor/autoload.php';

use MatchEngine\OrderBook;

verifyOs();

$config = parse_ini_file(dirname(__FILE__) . '/config/conf.ini', true);
$orderBook = new OrderBook($config['redis']);
$http = new Swoole\Http\Server($config['server']['host'], $config['server']['port']);

$http->on('request', function ($request, $response) use ($orderBook) {
    $response->header("Content-Type", "application/json; charset=utf-8");
    if ($request->server['path_info'] == '/favicon.ico' || $request->server['request_uri'] == '/favicon.ico') {
        return $response->end();
    }
    $result = verifySign($request);
    if ($result['status'] != 200) {
        return $response->end(toJson(0, $result['msg']));
    }
    $order = json_decode($request->get['params'], true);
    if (!is_array($order)) {
        return $response->end(toJson(0, 'err', 'Order Info Error'));
    }
    switch ($order['type']) {
        case 'order':   //订单处理
            list($status, $data) = $orderBook->processOrder($order['data']);
            break;
        case 'handicap'://盘口数据
            list($status, $data) = $orderBook->getHandicap($order['data']['market'], $order['data']['slice']);
            break;
        case 'empty':   //清空数据
            list($status, $data) = $orderBook->empty();
            break;
        case 'cancel':  //取消订单
            list($status, $data) = $orderBook->removeOrder($order['data']['market'], 'limit', $order['data']['side'], $order['data']['order_id']);
            break;
        default:
            list($status, $data) = [0, 'error data!'];
    }
    $response->end(toJson($status, $order['type'], $data));
//    $response->end("<h1>Hello Swoole. #" . rand(1000, 9999) . "</h1>");
});

dumpInfo(sprintf('Http Service Started Successfully At Port %s', $config['server']['port']));
$http->start();

/**
 * 验证签名
 * @param $request
 * @return array
 */
function verifySign($request)
{
    global $config;

    $result = [
        'status' => 200,
        'msg'    => 'Success'
    ];
    if (!isset($request->header['sign']) || !isset($request->header['timestamp'])) {
        $result['status'] = 401;
        $result['msg'] = 'Params Error';
    }
    if ($request->header['sign'] != strtoupper(sha1($request->header['timestamp'] . $config['verifySign']['sign']))) {
        //非法请求
        $result['status'] = 401;
        $result['msg'] = 'Access denied';
    }
    if (time() - $request->header['timestamp'] >= 2) {
        //超时请求
        $result['status'] = 401;
        $result['msg'] = 'Request Timeout';
    }

    return $result;
}

/**
 * 验证环境
 */
function verifyOs()
{
    if (version_compare(PHP_VERSION, '7.0', '<')) die('require PHP > 7.0 !');
    if (!extension_loaded('swoole')) die('Swoole extension does not exist !');
    if (!extension_loaded('redis')) die('Redis extension does not exist !');
}

/**
 * 格式化输出
 * @param $code
 * @param $type
 * @param array $data
 * @return false|string
 */
function toJson($code, $type, $data = [])
{
    $arr = [
        'code'      => $code,
        'timestamp' => time(),
        'type'      => $type,
        'data'      => $data,
    ];
    if (!$code) {
        $arr['err'] = $data;
    }

    return json_encode($arr);
}

/**
 * 日志输出
 * @param $msg
 */
function dumpInfo($msg)
{
    echo sprintf('[%s] %s', date('Y-m-d H:i:s'), $msg) . PHP_EOL;
}